using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using DocumentCreationSystem.Models;

namespace DocumentCreationSystem.Services
{
    /// <summary>
    /// AI助手工具服务
    /// 提供文件操作、内容分析、智能搜索等功能
    /// </summary>
    public class AgentToolService
    {
        private readonly ILogger<AgentToolService> _logger;
        private Project? _currentProject;
        private string? _workingDirectory;
        private string? _allowedProjectPath; // 允许访问的项目路径

        public AgentToolService(ILogger<AgentToolService> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 设置当前项目
        /// </summary>
        public void SetCurrentProject(Project? project)
        {
            _currentProject = project;
            // 设置允许访问的项目路径
            _allowedProjectPath = project?.RootPath;
            _logger.LogInformation($"Agent工具服务项目路径已设置为: {_allowedProjectPath ?? "无限制"}");
        }

        /// <summary>
        /// 设置工作目录
        /// </summary>
        public void SetWorkingDirectory(string? directory)
        {
            // 只有当目录在允许的项目路径下时才设置
            if (directory != null && _allowedProjectPath != null)
            {
                var normalizedDirectory = Path.GetFullPath(directory);
                var normalizedAllowedPath = Path.GetFullPath(_allowedProjectPath);

                if (normalizedDirectory.StartsWith(normalizedAllowedPath, StringComparison.OrdinalIgnoreCase))
                {
                    _workingDirectory = directory;
                    _logger.LogInformation($"Agent工具服务工作目录已设置为: {directory}");
                }
                else
                {
                    _logger.LogWarning($"拒绝设置工作目录，路径超出允许范围: {directory}");
                    _workingDirectory = _allowedProjectPath; // 回退到项目根路径
                }
            }
            else
            {
                _workingDirectory = directory;
                _logger.LogInformation($"Agent工具服务工作目录已设置为: {directory ?? "默认"}");
            }
        }

        /// <summary>
        /// 执行工具命令
        /// </summary>
        public async Task<string> ExecuteToolAsync(string toolName, string parameters, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogInformation($"执行工具: {toolName}, 参数: {parameters}");

                return toolName.ToLower() switch
                {
                    // 基础文件操作
                    "read_file" => await ReadFileAsync(parameters),
                    "write_file" => await WriteFileAsync(parameters),
                    "list_files" => await ListFilesAsync(parameters),

                    // 高级检索工具
                    "scan_project_structure" => await ScanProjectStructureAsync(parameters),
                    "get_file_summary" => await GetFileSummaryAsync(parameters),
                    "analyze_file_relationships" => await AnalyzeFileRelationshipsAsync(parameters),
                    "deep_content_search" => await DeepContentSearchAsync(parameters),
                    "get_project_overview" => await GetProjectOverviewAsync(parameters),

                    _ => $"未知工具: {toolName}"
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"执行工具失败: {toolName}");
                return $"❌ 执行工具失败: {ex.Message}";
            }
        }

        #region 基础文件操作

        /// <summary>
        /// 读取文件内容
        /// </summary>
        private async Task<string> ReadFileAsync(string parameters)
        {
            try
            {
                var filePath = GetFullPath(parameters.Trim());
                
                if (!File.Exists(filePath))
                {
                    return $"❌ 文件不存在: {parameters}";
                }

                var content = await File.ReadAllTextAsync(filePath);
                return $"📄 **文件内容**\n文件: {Path.GetFileName(filePath)}\n\n{content}";
            }
            catch (Exception ex)
            {
                return $"❌ 读取文件失败: {ex.Message}";
            }
        }

        /// <summary>
        /// 写入文件内容
        /// </summary>
        private async Task<string> WriteFileAsync(string parameters)
        {
            try
            {
                var parts = parameters.Split('|', 2);
                if (parts.Length < 2)
                {
                    return "❌ 参数格式错误，应为: 文件路径|文件内容";
                }

                var filePath = GetFullPath(parts[0].Trim());
                var content = parts[1];

                await File.WriteAllTextAsync(filePath, content);
                return $"✅ 文件写入成功: {Path.GetFileName(filePath)}";
            }
            catch (Exception ex)
            {
                return $"❌ 写入文件失败: {ex.Message}";
            }
        }

        /// <summary>
        /// 列出文件
        /// </summary>
        private async Task<string> ListFilesAsync(string parameters)
        {
            try
            {
                var targetPath = string.IsNullOrEmpty(parameters) ?
                    (_workingDirectory ?? _currentProject?.RootPath ?? Directory.GetCurrentDirectory()) :
                    GetFullPath(parameters.Trim());

                if (string.IsNullOrEmpty(targetPath) || !Directory.Exists(targetPath))
                {
                    return "❌ 无效的目录路径";
                }

                var files = Directory.GetFiles(targetPath, "*.*", SearchOption.TopDirectoryOnly)
                                   .Take(20)
                                   .Select(f => $"📄 {Path.GetFileName(f)}")
                                   .ToList();

                var directories = Directory.GetDirectories(targetPath)
                                          .Take(10)
                                          .Select(d => $"📁 {Path.GetFileName(d)}/")
                                          .ToList();

                var result = new StringBuilder();
                result.AppendLine($"📁 **目录内容** ({targetPath})");
                result.AppendLine();
                
                if (directories.Any())
                {
                    result.AppendLine("**文件夹:**");
                    result.AppendLine(string.Join("\n", directories));
                    result.AppendLine();
                }
                
                if (files.Any())
                {
                    result.AppendLine("**文件:**");
                    result.AppendLine(string.Join("\n", files));
                }

                return result.ToString();
            }
            catch (Exception ex)
            {
                return $"❌ 列出文件失败: {ex.Message}";
            }
        }

        #endregion

        #region 高级检索工具

        /// <summary>
        /// 扫描项目结构
        /// </summary>
        private async Task<string> ScanProjectStructureAsync(string parameters)
        {
            try
            {
                var targetPath = string.IsNullOrEmpty(parameters) ?
                    (_workingDirectory ?? _currentProject?.RootPath ?? Directory.GetCurrentDirectory()) :
                    parameters.Trim();

                if (string.IsNullOrEmpty(targetPath) || !Directory.Exists(targetPath))
                {
                    return "❌ 无效的项目路径或项目路径不存在";
                }

                var result = new StringBuilder();
                result.AppendLine($"📁 **项目结构扫描结果**");
                result.AppendLine($"📍 路径: {targetPath}");
                
                var files = Directory.GetFiles(targetPath, "*.*", SearchOption.AllDirectories);
                var directories = Directory.GetDirectories(targetPath, "*", SearchOption.AllDirectories);
                
                result.AppendLine($"📊 统计: {files.Length} 个文件, {directories.Length} 个文件夹");
                result.AppendLine();
                result.AppendLine("🌳 **目录结构**:");
                
                // 显示前20个文件和文件夹
                var allItems = files.Concat(directories).OrderBy(x => x).Take(20);
                foreach (var item in allItems)
                {
                    var relativePath = Path.GetRelativePath(targetPath, item);
                    var icon = Directory.Exists(item) ? "📁" : GetFileIcon(Path.GetExtension(item));
                    result.AppendLine($"  {icon} {relativePath}");
                }
                
                if (files.Length + directories.Length > 20)
                {
                    result.AppendLine($"  ... 还有 {files.Length + directories.Length - 20} 个项目");
                }

                return result.ToString();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"扫描项目结构失败: {parameters}");
                return $"❌ 扫描项目结构失败: {ex.Message}";
            }
        }

        /// <summary>
        /// 获取文件摘要
        /// </summary>
        private async Task<string> GetFileSummaryAsync(string parameters)
        {
            try
            {
                var filePath = GetFullPath(parameters.Trim());
                
                if (!File.Exists(filePath))
                {
                    return $"❌ 文件不存在: {parameters}";
                }

                var content = await File.ReadAllTextAsync(filePath);
                var fileInfo = new FileInfo(filePath);
                var lines = content.Split('\n');
                var words = content.Split(new char[] { ' ', '\n', '\r', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                
                // 生成简单摘要
                var summary = content.Length > 300 ? content.Substring(0, 300) + "..." : content;
                
                return $"📄 **文件摘要**\n" +
                       $"📍 文件: {Path.GetFileName(filePath)}\n" +
                       $"📊 大小: {fileInfo.Length} 字节, {lines.Length} 行, {words.Length} 词\n" +
                       $"📅 修改时间: {fileInfo.LastWriteTime:yyyy-MM-dd HH:mm:ss}\n\n" +
                       $"📝 **内容预览**:\n{summary}";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取文件摘要失败: {parameters}");
                return $"❌ 获取文件摘要失败: {ex.Message}";
            }
        }

        /// <summary>
        /// 分析文件关系
        /// </summary>
        private async Task<string> AnalyzeFileRelationshipsAsync(string parameters)
        {
            try
            {
                var targetPath = string.IsNullOrEmpty(parameters) ? _currentProject?.RootPath : parameters.Trim();
                
                if (string.IsNullOrEmpty(targetPath) || !Directory.Exists(targetPath))
                {
                    return "❌ 无效的项目路径";
                }

                var files = Directory.GetFiles(targetPath, "*.txt", SearchOption.AllDirectories)
                           .Concat(Directory.GetFiles(targetPath, "*.md", SearchOption.AllDirectories))
                           .Take(10) // 限制分析文件数量
                           .ToList();

                var result = new StringBuilder();
                result.AppendLine($"🔍 **文件关系分析**");
                result.AppendLine($"📊 分析了 {files.Count} 个文件");
                result.AppendLine();

                // 简单的文件名相似性分析
                var relationships = new List<string>();
                for (int i = 0; i < files.Count; i++)
                {
                    for (int j = i + 1; j < files.Count; j++)
                    {
                        var name1 = Path.GetFileNameWithoutExtension(files[i]).ToLower();
                        var name2 = Path.GetFileNameWithoutExtension(files[j]).ToLower();
                        
                        if (name1.Contains("章") && name2.Contains("章"))
                        {
                            relationships.Add($"🔗 {Path.GetFileName(files[i])} ↔ {Path.GetFileName(files[j])}: 都是章节文件");
                        }
                        else if (name1.Contains(name2) || name2.Contains(name1))
                        {
                            relationships.Add($"🔗 {Path.GetFileName(files[i])} ↔ {Path.GetFileName(files[j])}: 名称相似");
                        }
                    }
                }

                if (relationships.Any())
                {
                    result.AppendLine("**关联关系**:");
                    foreach (var rel in relationships.Take(10))
                    {
                        result.AppendLine(rel);
                    }
                }
                else
                {
                    result.AppendLine("未发现明显的文件关联关系");
                }

                return result.ToString();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"分析文件关系失败: {parameters}");
                return $"❌ 分析文件关系失败: {ex.Message}";
            }
        }

        /// <summary>
        /// 深度内容搜索
        /// </summary>
        private async Task<string> DeepContentSearchAsync(string parameters)
        {
            try
            {
                var parts = parameters.Split('|');
                if (parts.Length < 1)
                {
                    return "❌ 参数格式错误，应为: 搜索关键词|[搜索路径]";
                }

                var keyword = parts[0].Trim();
                var searchPath = parts.Length > 1 ? parts[1].Trim() : _currentProject?.RootPath;

                if (string.IsNullOrEmpty(searchPath) || !Directory.Exists(searchPath))
                {
                    return "❌ 搜索路径无效";
                }

                var results = new List<string>();
                var files = Directory.GetFiles(searchPath, "*.txt", SearchOption.AllDirectories)
                           .Concat(Directory.GetFiles(searchPath, "*.md", SearchOption.AllDirectories))
                           .Take(20) // 限制搜索文件数量
                           .ToList();

                foreach (var file in files)
                {
                    try
                    {
                        var content = await File.ReadAllTextAsync(file);
                        var lines = content.Split('\n');

                        for (int i = 0; i < lines.Length; i++)
                        {
                            if (lines[i].Contains(keyword, StringComparison.OrdinalIgnoreCase))
                            {
                                var context = $"第{i+1}行: {lines[i].Trim()}";
                                results.Add($"📄 **{Path.GetFileName(file)}**: {context}");

                                if (results.Count >= 10) break; // 限制结果数量
                            }
                        }
                    }
                    catch
                    {
                        // 忽略无法读取的文件
                    }

                    if (results.Count >= 10) break;
                }

                return $"🔍 **深度内容搜索结果**\n" +
                       $"🔎 关键词: {keyword}\n" +
                       $"📊 搜索了 {files.Count} 个文件，找到 {results.Count} 个匹配项\n\n" +
                       $"{string.Join("\n", results)}";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"深度内容搜索失败: {parameters}");
                return $"❌ 深度内容搜索失败: {ex.Message}";
            }
        }

        /// <summary>
        /// 获取项目概览
        /// </summary>
        private async Task<string> GetProjectOverviewAsync(string parameters)
        {
            try
            {
                var targetPath = string.IsNullOrEmpty(parameters) ? _currentProject?.RootPath : parameters.Trim();

                if (string.IsNullOrEmpty(targetPath) || !Directory.Exists(targetPath))
                {
                    return "❌ 无效的项目路径";
                }

                var allFiles = Directory.GetFiles(targetPath, "*.*", SearchOption.AllDirectories);
                var textFiles = allFiles.Where(f =>
                    f.EndsWith(".txt", StringComparison.OrdinalIgnoreCase) ||
                    f.EndsWith(".md", StringComparison.OrdinalIgnoreCase) ||
                    f.EndsWith(".docx", StringComparison.OrdinalIgnoreCase)).ToList();

                var totalSize = allFiles.Sum(f => new FileInfo(f).Length);
                var fileTypes = allFiles.GroupBy(f => Path.GetExtension(f).ToLower())
                                      .ToDictionary(g => g.Key, g => g.Count());

                var result = new StringBuilder();
                result.AppendLine($"📊 **项目概览**");
                result.AppendLine($"📍 路径: {targetPath}");
                result.AppendLine($"📁 总文件数: {allFiles.Length}");
                result.AppendLine($"📝 文本文件: {textFiles.Count}");
                result.AppendLine($"💾 总大小: {FormatFileSize(totalSize)}");
                result.AppendLine();

                result.AppendLine("📋 **文件类型分布**:");
                foreach (var type in fileTypes.Take(10))
                {
                    result.AppendLine($"• {type.Key}: {type.Value} 个");
                }

                result.AppendLine();
                result.AppendLine("📖 **主要文件**:");
                foreach (var file in textFiles.Take(10))
                {
                    var fileName = Path.GetFileName(file);
                    var fileSize = new FileInfo(file).Length;
                    result.AppendLine($"• {fileName} ({FormatFileSize(fileSize)})");
                }

                return result.ToString();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取项目概览失败: {parameters}");
                return $"❌ 获取项目概览失败: {ex.Message}";
            }
        }

        #endregion

        #region 辅助方法

        /// <summary>
        /// 获取完整路径，并验证是否在允许的项目路径范围内
        /// </summary>
        private string GetFullPath(string path)
        {
            string fullPath;

            if (Path.IsPathRooted(path))
            {
                fullPath = path;
            }
            else
            {
                // 优先使用工作目录，然后是当前项目路径，最后是当前工作目录
                var basePath = _workingDirectory ?? _currentProject?.RootPath ?? Directory.GetCurrentDirectory();
                fullPath = Path.Combine(basePath, path);
            }

            // 验证路径是否在允许的项目路径范围内
            if (_allowedProjectPath != null)
            {
                var normalizedFullPath = Path.GetFullPath(fullPath);
                var normalizedAllowedPath = Path.GetFullPath(_allowedProjectPath);

                if (!normalizedFullPath.StartsWith(normalizedAllowedPath, StringComparison.OrdinalIgnoreCase))
                {
                    _logger.LogWarning($"拒绝访问路径，超出允许范围: {path} -> {normalizedFullPath}");
                    throw new UnauthorizedAccessException($"访问被拒绝：路径超出项目范围 {path}");
                }
            }

            return fullPath;
        }

        /// <summary>
        /// 获取文件图标
        /// </summary>
        private string GetFileIcon(string extension)
        {
            return extension.ToLower() switch
            {
                ".txt" => "📄",
                ".md" => "📝",
                ".docx" => "📘",
                ".pdf" => "📕",
                ".json" => "📋",
                ".xml" => "📄",
                ".html" => "🌐",
                ".css" => "🎨",
                ".js" => "⚡",
                ".cs" => "💻",
                ".py" => "🐍",
                ".jpg" or ".jpeg" or ".png" or ".gif" => "🖼️",
                ".mp3" or ".wav" => "🎵",
                ".mp4" or ".avi" => "🎬",
                _ => "📄"
            };
        }

        /// <summary>
        /// 格式化文件大小
        /// </summary>
        private string FormatFileSize(long bytes)
        {
            string[] sizes = { "B", "KB", "MB", "GB", "TB" };
            double len = bytes;
            int order = 0;
            while (len >= 1024 && order < sizes.Length - 1)
            {
                order++;
                len = len / 1024;
            }
            return $"{len:0.##} {sizes[order]}";
        }

        #endregion
    }
}
